package com.android.webframework.nav;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import com.android.webframework.R;
import com.android.webframework.RequestException;
import com.android.webframework.RequestObject;
import com.android.webframework.Step;
import com.android.webframework.WebFramework;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;
import com.google.android.maps.Overlay;

import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class DirectionsActivity extends MapActivity {
	
	private MediaPlayer mMediaPlayer;
	private WebFramework mWebWrapper;
	
	private MapView mMap;
	private MapController mMapControl;
	private List<Overlay> mOverlays;
	private MyLocationOverlay mLocOverlay;
	
	private TextView mDirections;
	private TextView mSource;
	private TextView mDestination;
	private Button mPrevious;
	private Button mPlay;
	private Button mNext;
	
	private Bundle mBundle;
	
	private ArrayList<Step> mSteps;
	private String[] mStringDirections;
	private GeoPoint[] mStarts;
	private GeoPoint[] mEnds;
	private int iterator;
	
	private LocationManager mLocManager;
	private LocationListener mLocListener;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.directions);
		
		//Set up location service
		setUpLocationService();
		
		//Initialize Views
		mDirections = (TextView) findViewById(R.id.directions);
		mSource = (TextView) findViewById(R.id.mSource);
		mDestination = (TextView) findViewById(R.id.mDestination);
		mPrevious = (Button) findViewById(R.id.previous);
		mPlay = (Button) findViewById(R.id.play);
		mNext = (Button) findViewById(R.id.next);
		
		//MapView
		mMap = (MapView) findViewById(R.id.mapView);
		mLocOverlay = new MyLocationOverlay(this, mMap);
		mMap.setBuiltInZoomControls(true);
		mMapControl = mMap.getController();
		mMapControl.setZoom(14);
		
		//Get input from StartActivity
		mBundle = getIntent().getExtras();
		
		//Populate Source and Destination
		mSource.setText(mBundle.getString("source").toString());
		mDestination.setText(mBundle.getString("destination").toString());
		
		mSteps = (ArrayList<Step>) mBundle.getSerializable("directions");
		
		mStringDirections = new String[mSteps.size()];
		for(int i = 0; i < mSteps.size(); i++) {
			mStringDirections[i] = mSteps.get(i).instruction();
		}
		mStarts = new GeoPoint[mSteps.size()];
		for(int i = 0; i < mSteps.size(); i++) {
			mStarts[i] = new GeoPoint((int)(mSteps.get(i).startLat()*1E6),(int)(mSteps.get(i).startLon()*1E6));
		}
		mEnds = new GeoPoint[mSteps.size()];
		for(int i = 0; i < mSteps.size(); i++) {
			mEnds[i] = new GeoPoint((int)(mSteps.get(i).endLat()*1E6), (int)(mSteps.get(i).endLon()*1E6));
		}
		
		iterator = 0;
		mDirections.setText(mStringDirections[iterator].replaceAll("\\+", " "));
		
		//Register Button listeners
		mPrevious.setOnClickListener(new OnClickListener(){

			public void onClick(View v) {
				// TODO Auto-generated method stub
				//update mDirections
				if(iterator-1 >= 0) {
					mDirections.setText(mStringDirections[--iterator]);
					//call mPlay's onclicklistener
					mPlay.performClick();
				}else {
					Toast.makeText(DirectionsActivity.this, "No previous direction", Toast.LENGTH_SHORT).show();
				}				
			}
			
		});
		mPlay.setOnClickListener(new OnClickListener(){

			public void onClick(View v) {
				
				//TEST TEXT-TO-SPEECH
				String mString = mDirections.getText().toString();
				
				//Take out + for cleanDirections
				mString = mString.replaceAll("\\+", " ");
				
				//Format the string for speech
				mString = cleanDirections(mString);
				
				//Replace the ' ' to '+' for url
				mString = mString.replaceAll(" ", "+");
			
				mWebWrapper = new WebFramework();
				mWebWrapper.setRequestType("tts");
				mWebWrapper.addParameter("text", mString);
				
				//Replace the '+' back to ' ' 
				mString = mString.replaceAll("\\+", " ");			
				mDirections.setText(mString);

				mMediaPlayer = new MediaPlayer();
				try {
					mWebWrapper.request();
					mMediaPlayer.setDataSource(((File)mWebWrapper.response().getResponse()).getAbsolutePath());
					mMediaPlayer.prepare();
					mMediaPlayer.start();
				} catch (Exception e){
					System.out.println(e);
				}
				
			}
			
		});
		mNext.setOnClickListener(new OnClickListener(){

			public void onClick(View v) {
				// TODO Auto-generated method stub
				//update mDirections
				if(iterator+1 < mStringDirections.length) {
					mDirections.setText(mStringDirections[++iterator]);
					//call mPlay's onclicklistener
					mPlay.performClick();
				}else {
					Toast.makeText(DirectionsActivity.this, "No next direction", Toast.LENGTH_SHORT).show();
				}
			}
			
		});
		
		//Play the first direction when app starts
		//mPlay.performClick();
		
		//Add Overlays to the mapView
		mOverlays = mMap.getOverlays();
		//Drawable mIcon = getResources().getDrawable(R.drawable.ic_launcher);
		//NavItemizedOverlay itemizedOverlay = new NavItemizedOverlay(mIcon, this);
		
		Location loc = mLocManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
		//GeoPoint point = new GeoPoint((int) (loc.getLatitude()*1E6), (int) (loc.getLongitude()*1E6));
		//mMap.getProjection().toPixels(point, new Point());
		//OverlayItem icon = new OverlayItem(point, "Current Location", "");
		//itemizedOverlay.addOverlay(icon);
		//mapOverlays.add(itemizedOverlay);
		mOverlays.add(mLocOverlay);//location
		
		//test line from current to Miami 
		//mOverlays.add(new RouteOverlay(point,new GeoPoint((int)(25.82*1E6), -(int)(80.28*1E6))));
		for(int i = 0; i < mStarts.length; i++) {
			mOverlays.add(new RouteOverlay(mStarts[i]));
			mOverlays.add(new RouteOverlay(mStarts[i], mEnds[i]));
			mOverlays.add(new RouteOverlay(mEnds[i]));
		}
	}

	private void setUpLocationService() {
		//Get a reference to the device's Location Manager
		mLocManager = (LocationManager) getSystemService(LOCATION_SERVICE);
		
		//Define a location listener
		mLocListener = new LocationListener() {

			public void onLocationChanged(Location loc) {
				// TODO Auto-generated method stub
				mMapControl.animateTo(new GeoPoint((int) (loc.getLatitude()*1E6), (int) (loc.getLongitude()*1E6)));
			}

			public void onProviderDisabled(String arg0) {
				// TODO Auto-generated method stub
				
			}

			public void onProviderEnabled(String arg0) {
				// TODO Auto-generated method stub
				
			}

			public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
				// TODO Auto-generated method stub
				
			}
			
		};
		
		//Register the listener with the manager
		mLocManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, mLocListener);//change it later to not update so much
	}

	private String cleanDirections(String mString) {
		//Add padding to end of line
		mString += " ";
		
		//Other Google API things
		mString = mString.replaceAll("Toll road|Partial toll road", "");
		mString = mString.replaceAll("\\wDestination will be on the left", " . Destination will be on the left");
		mString = mString.replaceAll("\\wDestination will be on the right", " . Destination will be on the right");
		
		// All cardinal directions (N, S, E, W, NE, SE, NW, SW)
		mString = mString.replaceAll(" N | N\\z", " North ");
		mString = mString.replaceAll(" S | S\\z", " South ");
		mString = mString.replaceAll(" E | E\\z", " East ");
		mString = mString.replaceAll(" W | W\\z", " West ");
		mString = mString.replaceAll("SW", " Southwest ");
		mString = mString.replaceAll("SE", " Southeast ");
		mString = mString.replaceAll("NE", " Northeast ");
		mString = mString.replaceAll("NW", " Northwest ");
		mString = mString.replaceAll(" N/", " North ");
		mString = mString.replaceAll(" S/", " South ");
		mString = mString.replaceAll(" E/", " East ");
		mString = mString.replaceAll(" W/", " West ");
		
		mString = mString.replaceAll("US", "U.S.");
		mString = mString.replaceAll("-", " ");
		mString = mString.replaceAll("/", " ");
		mString = mString.replaceAll(" CR ", " County Road ");
		mString = mString.replaceAll(" SR ", " State Road ");
		
		/*mString = mString.replaceAll("AA", " 	Armed Forces Americas ");
		mString = mString.replaceAll("AE", " 	Armed Forces Europe ");
		mString = mString.replaceAll("AK", " 	Alaska ");
		mString = mString.replaceAll("AL", " 	Alabama ");
		mString = mString.replaceAll("AP", " 	Armed Forces Pacific ");
		mString = mString.replaceAll("AR", " 	Arkansas ");
		mString = mString.replaceAll("AS", " 	American Somoa ");
		mString = mString.replaceAll("AZ", " 	Arizona ");
		mString = mString.replaceAll("CA", " 	California ");
		mString = mString.replaceAll("CO", " 	Colorado ");
		mString = mString.replaceAll("CT", " 	Connecticut ");
		mString = mString.replaceAll("DC", " 	District of Columbia ");
		mString = mString.replaceAll("DE", " 	Delaware ");
		mString = mString.replaceAll("FL", " 	Florida ");
		mString = mString.replaceAll("FM", " 	Federated States of Micronesia ");
		mString = mString.replaceAll("GA", " 	Georgia ");
		mString = mString.replaceAll("GU", " 	Guam ");
		mString = mString.replaceAll("HI", " 	Hawaii ");
		mString = mString.replaceAll("IA", " 	Iowa ");
		mString = mString.replaceAll("ID", " 	Idaho ");
		mString = mString.replaceAll("IL", " 	Illinois ");
		mString = mString.replaceAll("IN", " 	Indiana ");
		mString = mString.replaceAll("KS", " 	Kansas ");
		mString = mString.replaceAll("KY", " 	Kentucky ");
		mString = mString.replaceAll("LA", " 	Louisiana ");
		mString = mString.replaceAll("MA", " 	Massachusetts ");
		mString = mString.replaceAll("MD", " 	Maryland ");
		mString = mString.replaceAll("ME", " 	Maine ");
		mString = mString.replaceAll("MH", " 	Marshall Islands ");
		mString = mString.replaceAll("MI", " 	Michigan ");
		mString = mString.replaceAll("MN", " 	Minnesota ");
		mString = mString.replaceAll("MO", " 	Missouri ");
		mString = mString.replaceAll("MP", " 	Northern Mariana Islands ");
		mString = mString.replaceAll("MS", " 	Mississippi ");
		mString = mString.replaceAll("MT", " 	Montana ");
		mString = mString.replaceAll("NC", " 	North Carolina ");
		mString = mString.replaceAll("ND", " 	North Dakota ");
		mString = mString.replaceAll("NE", " 	Nebraska ");
		mString = mString.replaceAll("NH", " 	New Hampshire ");
		mString = mString.replaceAll("NJ", " 	New Jersey ");
		mString = mString.replaceAll("NM", " 	New Mexico ");
		mString = mString.replaceAll("NV", " 	Nevada ");
		mString = mString.replaceAll("NY", " 	New York ");
		mString = mString.replaceAll("OH", " 	Ohio ");
		mString = mString.replaceAll("OK", " 	Oklahoma ");
		mString = mString.replaceAll("OR", " 	Oregon ");
		mString = mString.replaceAll("PA", " 	Pennsylvania ");
		mString = mString.replaceAll("PR", " 	Puerto Rico ");
		mString = mString.replaceAll("PW", " 	Palau ");
		mString = mString.replaceAll("RI", " 	Rhode Island ");
		mString = mString.replaceAll("SC", " 	South Carolina ");
		mString = mString.replaceAll("SD", " 	South Dakota ");
		mString = mString.replaceAll("TN", " 	Tennessee ");
		mString = mString.replaceAll("TX", " 	Texas ");
		mString = mString.replaceAll("UT", " 	Utah ");
		mString = mString.replaceAll("VA", " 	Virginia ");
		mString = mString.replaceAll("VI", " 	Virgin Islands ");
		mString = mString.replaceAll("VT", " 	Vermont ");
		mString = mString.replaceAll("WA", " 	Washington ");
		mString = mString.replaceAll("WI", " 	Wisconsin ");
		mString = mString.replaceAll("WV", " 	West Virginia ");
		mString = mString.replaceAll("WY", " 	Wyoming ");*/
		
		mString = mString.replaceAll(" Aly ", " Alley ");
		mString = mString.replaceAll(" Anx ", " Annex ");
		mString = mString.replaceAll(" Apt ", " Apartment ");
		mString = mString.replaceAll(" Arc ", " Arcade ");
		mString = mString.replaceAll(" Ave ", " Avenue ");
		mString = mString.replaceAll(" Bsmt ", " Basement ");
		mString = mString.replaceAll(" Byu ", " Bayou ");
		mString = mString.replaceAll(" Bch ", " Beach ");
		mString = mString.replaceAll(" Bnd ", " Bend ");
		mString = mString.replaceAll(" Blf ", " Bluff ");
		mString = mString.replaceAll(" Btm ", " Bottom ");
		mString = mString.replaceAll(" Blvd ", " Boulevard ");
		mString = mString.replaceAll(" Br ", " Branch ");
		mString = mString.replaceAll(" Brg ", " Bridge ");
		mString = mString.replaceAll(" Brk ", " Brook ");
		mString = mString.replaceAll(" Bldg ", " Building ");
		mString = mString.replaceAll(" Bg ", " Burg ");
		mString = mString.replaceAll(" Byp ", " Bypass ");
		mString = mString.replaceAll(" Cp ", " Camp ");
		mString = mString.replaceAll(" Cyn ", " Canyon ");
		mString = mString.replaceAll(" Cpe ", " Cape ");
		mString = mString.replaceAll(" Cswy ", " Causeway ");
		mString = mString.replaceAll(" Ctr ", " Center ");
		mString = mString.replaceAll(" Cir ", " Circle ");
		mString = mString.replaceAll(" Clf ", " Cliff ");
		mString = mString.replaceAll(" Clfs ", " Cliffs ");
		mString = mString.replaceAll(" Clb ", " Club ");
		mString = mString.replaceAll(" Cor ", " Corner ");
		mString = mString.replaceAll(" Cors ", " Corners ");
		mString = mString.replaceAll(" Crse ", " Course ");
		mString = mString.replaceAll(" Ct ", " Court ");
		mString = mString.replaceAll(" Cts ", " Courts ");
		mString = mString.replaceAll(" Cv ", " Cove ");
		mString = mString.replaceAll(" Crk ", " Creek ");
		mString = mString.replaceAll(" Cres ", " Crescent ");
		mString = mString.replaceAll(" Xing ", " Crossing ");
		mString = mString.replaceAll(" Dl ", " Dale ");
		mString = mString.replaceAll(" Dm ", " Dam ");
		mString = mString.replaceAll(" Dept ", " Department ");
		mString = mString.replaceAll(" Dv ", " Divide ");
		mString = mString.replaceAll(" Dr ", " Drive ");
		mString = mString.replaceAll(" Est ", " Estate ");
		mString = mString.replaceAll(" Expy ", " Expressway ");
		mString = mString.replaceAll(" Ext ", " Extension ");
		mString = mString.replaceAll(" Fls ", " Falls ");
		mString = mString.replaceAll(" Fry ", " Ferry ");
		mString = mString.replaceAll(" Fld ", " Field ");
		mString = mString.replaceAll(" Flds ", " Fields ");
		mString = mString.replaceAll(" Flt ", " Flat ");
		mString = mString.replaceAll(" Fl ", " Floor ");
		mString = mString.replaceAll(" Frd ", " Ford ");
		mString = mString.replaceAll(" Frst ", " Forest ");
		mString = mString.replaceAll(" Frg ", " Forge ");
		mString = mString.replaceAll(" Frk ", " Fork ");
		mString = mString.replaceAll(" Frks ", " Forks ");
		mString = mString.replaceAll(" Ft ", " Fort ");
		mString = mString.replaceAll(" Fwy ", " Freeway ");
		mString = mString.replaceAll(" Frnt ", " Front ");
		mString = mString.replaceAll(" Gdn ", " Garden ");
		mString = mString.replaceAll(" Gdns ", " Gardens ");
		mString = mString.replaceAll(" Gtwy ", " Gateway ");
		mString = mString.replaceAll(" Gln ", " Glen ");
		mString = mString.replaceAll(" Grn ", " Green ");
		mString = mString.replaceAll(" Grv ", " Grove ");
		mString = mString.replaceAll(" Hngr ", " Hanger ");
		mString = mString.replaceAll(" Hbr ", " Harbor ");
		mString = mString.replaceAll(" Hvn ", " Haven ");
		mString = mString.replaceAll(" Hts ", " Heights ");
		mString = mString.replaceAll(" Hwy ", " Highway ");
		mString = mString.replaceAll(" Hl ", " Hill ");
		mString = mString.replaceAll(" Hls ", " Hills ");
		mString = mString.replaceAll(" Holw ", " Hollow ");
		mString = mString.replaceAll(" Inlt ", " Inlet ");
		mString = mString.replaceAll(" Is ", " Island ");
		mString = mString.replaceAll(" Iss ", " Islands ");
		mString = mString.replaceAll(" Jct ", " Junction ");
		mString = mString.replaceAll(" Ky ", " Key ");
		mString = mString.replaceAll(" Knl ", " Knoll ");
		mString = mString.replaceAll(" Knls ", " Knolls ");
		mString = mString.replaceAll(" Lk ", " Lake ");
		mString = mString.replaceAll(" Lks ", " Lakes ");
		mString = mString.replaceAll(" Lndg ", " Landing ");
		mString = mString.replaceAll(" Ln ", " Lane ");
		mString = mString.replaceAll(" Lgt ", " Light ");
		mString = mString.replaceAll(" Lf ", " Loaf ");
		mString = mString.replaceAll(" Lbby ", " Lobby ");
		mString = mString.replaceAll(" Lck ", " Lock ");
		mString = mString.replaceAll(" Lcks ", " Locks ");
		mString = mString.replaceAll(" Ldg ", " Lodge ");
		mString = mString.replaceAll(" Lowr ", " Lower ");
		mString = mString.replaceAll(" Mnr ", " Manor ");
		mString = mString.replaceAll(" Mdw ", " Meadow ");
		mString = mString.replaceAll(" Mdws ", " Meadows ");
		mString = mString.replaceAll(" Ml ", " Mill ");
		mString = mString.replaceAll(" Mls ", " Mills ");
		mString = mString.replaceAll(" Msn ", " Mission ");
		mString = mString.replaceAll(" Mt ", " Mount ");
		mString = mString.replaceAll(" Mtn ", " Mountain ");
		mString = mString.replaceAll(" Nck ", " Neck ");
		mString = mString.replaceAll(" Ofc ", " Office ");
		mString = mString.replaceAll(" Orch ", " Orchard ");
		mString = mString.replaceAll(" Pkwy ", " Parkway ");
		mString = mString.replaceAll(" Ph ", " Penthouse ");
		mString = mString.replaceAll(" Pne ", " Pine ");
		mString = mString.replaceAll(" Pnes ", " Pines ");
		mString = mString.replaceAll(" Pl ", " Place ");
		mString = mString.replaceAll(" Pln ", " Plain ");
		mString = mString.replaceAll(" Plns ", " Plains ");
		mString = mString.replaceAll(" Plz ", " Plaza ");
		mString = mString.replaceAll(" Pt ", " Point ");
		mString = mString.replaceAll(" Prt ", " Port ");
		mString = mString.replaceAll(" Pr ", " Prairie ");
		mString = mString.replaceAll(" Radl ", " Radial ");
		mString = mString.replaceAll(" Rnch ", " Ranch ");
		mString = mString.replaceAll(" Rpd ", " Rapid ");
		mString = mString.replaceAll(" Rpds ", " Rapids ");
		mString = mString.replaceAll(" Rst ", " Rest ");
		mString = mString.replaceAll(" Rdg ", " Ridge ");
		mString = mString.replaceAll(" Riv ", " River ");
		mString = mString.replaceAll(" Rd ", " Road ");
		mString = mString.replaceAll(" Rm ", " Room ");
		mString = mString.replaceAll(" Shl ", " Shoal ");
		mString = mString.replaceAll(" Shls ", " Shoals ");
		mString = mString.replaceAll(" Shr ", " Shore ");
		mString = mString.replaceAll(" Shrs ", " Shores ");
		mString = mString.replaceAll(" Spc ", " Space ");
		mString = mString.replaceAll(" Spg ", " Spring ");
		mString = mString.replaceAll(" Spgs ", " Springs ");
		mString = mString.replaceAll(" Sq ", " Square ");
		mString = mString.replaceAll(" Sta ", " Station ");
		mString = mString.replaceAll(" Stra ", " Stravenue ");
		mString = mString.replaceAll(" Strm ", " Stream ");
		mString = mString.replaceAll(" St ", " Street ");
		mString = mString.replaceAll(" Ste ", " Suite ");
		mString = mString.replaceAll(" Smt ", " Summit ");
		mString = mString.replaceAll(" Ter ", " Terrace ");
		mString = mString.replaceAll(" Trce ", " Trace ");
		mString = mString.replaceAll(" Trak ", " Track ");
		mString = mString.replaceAll(" Trfy ", " Trafficway ");
		mString = mString.replaceAll(" Trl ", " Trail ");
		mString = mString.replaceAll(" Trlr ", " Trailer ");
		mString = mString.replaceAll(" Tunl ", " Tunnel ");
		mString = mString.replaceAll(" Tpke ", " Turnpike ");
		mString = mString.replaceAll(" Un ", " Union ");
		mString = mString.replaceAll(" Uppr ", " Upper ");
		mString = mString.replaceAll(" Vly ", " Valley ");
		mString = mString.replaceAll(" Via ", " Viaduct ");
		mString = mString.replaceAll(" Vw ", " View ");
		mString = mString.replaceAll(" Vlg ", " Village ");
		mString = mString.replaceAll(" Vl ", " Ville ");
		mString = mString.replaceAll(" Vis ", " Vista ");
		mString = mString.replaceAll(" Way ", " Way ");
		mString = mString.replaceAll(" Wl ", " Well ");
		mString = mString.replaceAll(" Wls ", " Wells ");
		
		// Fix ' not showing up right, i.e. ' = &#39;
		mString = mString.replaceAll("\\&#39;", "'");
		
		return mString;
	}

	@Override
	protected boolean isRouteDisplayed() {
		// TODO Auto-generated method stub FROM MapActivity
		return false;
	}

	@Override
	protected void onPause() {
		super.onPause();
		mLocManager.removeUpdates(mLocListener);

		mLocOverlay.disableMyLocation();
		mLocOverlay.disableCompass();
		System.out.println("onPaused");
	}

	@Override
	protected void onResume() {
		super.onResume();
		mLocManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, mLocListener);
		
		mLocOverlay.enableMyLocation();
		mLocOverlay.enableCompass();
		System.out.println("onResume");
	}

}
